package com.fulihui.wgj.service.template;

import com.alibaba.dubbo.config.annotation.Service;
import com.fulihui.common.builder.rpc.RpcResultBuilder;
import com.fulihui.common.conv.BeanConv;
import com.fulihui.common.enums.TemplateStatusEnum;
import com.fulihui.common.error.Errors;
import com.fulihui.common.error.InvokeServiceException;
import com.fulihui.common.request.rpc.AppRequest;
import com.fulihui.common.result.rpc.BaseResult;
import com.fulihui.common.result.rpc.SimpleResult;
import com.fulihui.common.util.ConditionValidator;
import com.fulihui.common.util.PlatformUtil;
import com.fulihui.weixinsdk.WeixinSDK;
import com.fulihui.weixinsdk.model.Template;
import com.fulihui.weixinsdk.request.template.TemplateGetRequest;
import com.fulihui.weixinsdk.result.template.TemplateGetResult;
import com.fulihui.wgj.dal.mybatis.domain.WxSendTemplateLog;
import com.fulihui.wgj.dal.mybatis.domain.WxTemplate;
import com.fulihui.wgj.dal.mybatis.repository.WxSendTemplateLogRepository;
import com.fulihui.wgj.dal.mybatis.repository.WxTemplateRepository;
import com.fulihui.wgj.facade.dto.WxTemplateDTO;
import com.fulihui.wgj.facade.request.template.TemplateLastUseQueryRequest;
import com.fulihui.wgj.facade.request.template.WxTemplateDeleteRequest;
import com.fulihui.wgj.facade.request.template.WxTemplatePageQueryRequest;
import com.fulihui.wgj.facade.request.template.WxTemplateQueryRequest;
import com.fulihui.wgj.facade.request.template.WxTemplateUpdateRequest;
import com.fulihui.wgj.facade.result.template.WxTemplatePageResult;
import com.fulihui.wgj.facade.service.template.WxTemplateService;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 微信模板Service
 *
 * @author wang_wx
 * @date 2018-07-25
 */
@Component
@Service(interfaceClass = WxTemplateService.class, version = "1.0.0", timeout = 5000)
public class WxTemplateServiceImpl implements WxTemplateService {

    private static final Logger LOGGER = LoggerFactory.getLogger(WxTemplateServiceImpl.class);

    @Autowired
    WxTemplateRepository wxTemplateRepository;

    @Autowired
    WxSendTemplateLogRepository wxSendTemplateLogRepository;

    @Autowired
    PlatformUtil platformUtil;
    @Autowired
    WeixinSDK weixinSDK;

    @Override
    public BaseResult syncTemplate(AppRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        String appId = request.getAppId();
        String cache = platformUtil.get(appId);
        if (StringUtils.isBlank(cache)) {
            return RpcResultBuilder.fail(Errors.Commons.TOKEN_DOES_NOT_EXIST);
        }
        TemplateGetRequest templateGetRequest = new TemplateGetRequest();
        templateGetRequest.setAccess_token(cache);
        // 微信返回的肯定是实时有效的
        TemplateGetResult templateGetResult = weixinSDK.invokeService(templateGetRequest);
        if (Objects.nonNull(templateGetResult)) {
            List<Template> templateList = templateGetResult.getTemplate_list();
            wxTemplateRepository.syncTemplate(appId, templateList);
        }
        LOGGER.info("syncTemplate complete." + appId);
        return RpcResultBuilder.succ();
    }

    @Override
    public SimpleResult<List<String>> queryDeputyIndustry(AppRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        List<String> industryList = wxTemplateRepository.queryDeputyIndustry(request.getAppId());
        return RpcResultBuilder.succSimple(industryList);
    }

    @Override
    public WxTemplatePageResult pageQueryTemplates(WxTemplatePageQueryRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        WxTemplate wxTemplate = BeanConv.copy(request, WxTemplate.class);
        PageInfo<WxTemplate> pageInfo = wxTemplateRepository.queryPageListByExample(buildExample(wxTemplate), request.getPage(), request.getRows());
        long total = pageInfo.getTotal();
        WxTemplatePageResult pageResult = RpcResultBuilder.succPageResult(WxTemplatePageResult.class, pageInfo.getPageNum(), pageInfo.getPageSize(), Math.toIntExact(total));
        if (total > 0) {
            pageResult.setValue(BeanConv.copy(pageInfo.getList(), WxTemplateDTO.class));
        }
        LOGGER.info("pageResult = {}", pageResult);
        return pageResult;
    }

    /**
     * 组装条件
     *
     * @param wxTemplate
     * @return
     */
    Example buildExample(WxTemplate wxTemplate) {
        Example example = new Example(WxTemplate.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("appId", wxTemplate.getAppId());
        Long status = wxTemplate.getStatus();
        criteria.andNotEqualTo("status", TemplateStatusEnum.delete.getValue());
        if (Objects.nonNull(status)) {
            criteria.andEqualTo("status", status);
        }
        String primaryIndustry = wxTemplate.getPrimaryIndustry();
        if (StringUtils.isNotBlank(primaryIndustry)) {
            criteria.andEqualTo("primaryIndustry", primaryIndustry);
        }
        String deputyIndustry = wxTemplate.getDeputyIndustry();
        if (StringUtils.isNotBlank(deputyIndustry)) {
            criteria.andEqualTo("deputyIndustry", deputyIndustry);
        }
        String title = wxTemplate.getTitle();
        if (StringUtils.isNotBlank(title)) {
            criteria.andLike("title", "%" + title + "%");
        }
        example.orderBy("gmtModified").desc();
        return example;
    }

    @Override
    public BaseResult deleteTemplate(WxTemplateDeleteRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        WxTemplate wxTemplate = wxTemplateRepository.queryById(request.getId());
        if (TemplateStatusEnum.valid.getCode().equals(wxTemplate.getStatus())) {
            return RpcResultBuilder.fail(Errors.WxTemplateError.CANNOT_DELETE_VALID_TEMPLATE);
        }
        WxTemplate wxTemplateUpdate = new WxTemplate();
        wxTemplateUpdate.setId(request.getId());
        wxTemplateUpdate.setStatus(TemplateStatusEnum.delete.getValue());
        wxTemplateUpdate.setGmtModified(new Date());
        Integer update = wxTemplateRepository.updateSelective(wxTemplateUpdate);
        return update > 0 ? RpcResultBuilder.succ() : RpcResultBuilder.fail(Errors.Commons.UPDATE_FAILED);
    }

    @Override
    public BaseResult updateTemplateStatus(WxTemplateUpdateRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        Long id = request.getId();
        String templateId = request.getTemplateId();
        if (Objects.isNull(id) && StringUtils.isBlank(templateId)) {
            return RpcResultBuilder.fail(Errors.WxTemplateError.PRIMARY_KEY_AND_TEMPLATE_ID_CANNOT_ALL_EMPTY);
        }
        Long status = request.getStatus();
        Integer count = 0;
        if (Objects.nonNull(id)) {
            WxTemplate wxTemplateUpdate = new WxTemplate();
            wxTemplateUpdate.setId(id);
            wxTemplateUpdate.setStatus(status);
            count = wxTemplateRepository.updateSelective(wxTemplateUpdate);
        } else if (StringUtils.isNotBlank(request.getTemplateId())) {
            WxTemplate wxTemplateUpdate = new WxTemplate();
            wxTemplateUpdate.setStatus(status);
            Example example = new Example(WxTemplate.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("templateId", request.getTemplateId());
            count = wxTemplateRepository.updateByExampleSelective(wxTemplateUpdate, example);
        }
        return count > 0 ? RpcResultBuilder.succ() : RpcResultBuilder.fail(Errors.Commons.UPDATE_FAILED);
    }


    @Override
    public SimpleResult<WxTemplateDTO> querySingleTemplate(WxTemplateQueryRequest request) throws InvokeServiceException {
        if (Objects.isNull(request.getId()) && StringUtils.isBlank(request.getTemplateId())) {
            return RpcResultBuilder.failSimple(Errors.WxTemplateError.PRIMARY_KEY_AND_TEMPLATE_ID_CANNOT_ALL_EMPTY);
        }
        WxTemplate wxTemplate = null;
        if (Objects.nonNull(request.getId())) {
            wxTemplate = wxTemplateRepository.queryById(request.getId());
        } else if (StringUtils.isNotBlank(request.getTemplateId())) {
            WxTemplate wxTemplateQuery = new WxTemplate();
            wxTemplateQuery.setTemplateId(request.getTemplateId());
            wxTemplate = wxTemplateRepository.queryOne(wxTemplateQuery);
        }
        WxTemplateDTO wxTemplateDTO = null;
        if (Objects.nonNull(wxTemplate)) {
//            if (TemplateStatusEnum.valid.getValue() != wxTemplate.getStatus().longValue()) {
//                return RpcResultBuilder.failSimple(Errors.WxTemplateError.THIS_TEMPLATE_IS_NOT_VALID);
//            }
            wxTemplateDTO = BeanConv.copy(wxTemplate, WxTemplateDTO.class);
        }
        return RpcResultBuilder.succSimple(wxTemplateDTO);
    }

    @Override
    public SimpleResult<WxTemplateDTO> queryLastUseTemplate(TemplateLastUseQueryRequest request) throws InvokeServiceException {
        ConditionValidator.validate(request);
        List<WxSendTemplateLog> wxSendTemplateLogs = wxSendTemplateLogRepository.queryByExample(buildLogExample(request));
        WxTemplateDTO wxTemplateDTO = null;
        if (!CollectionUtils.isEmpty(wxSendTemplateLogs)) {
            String templateId = wxSendTemplateLogs.get(0).getTemplateId();
            if (StringUtils.isNotBlank(templateId)) {
                WxTemplate wxTemplateQuery = new WxTemplate();
                wxTemplateQuery.setTemplateId(templateId);
                WxTemplate wxTemplate = wxTemplateRepository.queryOne(wxTemplateQuery);
                if (Objects.nonNull(wxTemplate)) {
                    if (TemplateStatusEnum.valid.getValue() != wxTemplate.getStatus().longValue()) {
                        return RpcResultBuilder.failSimple(Errors.WxTemplateError.THIS_TEMPLATE_IS_NOT_VALID);
                    }
                    wxTemplateDTO = BeanConv.copy(wxTemplate, WxTemplateDTO.class);
                }
            }
        }
        LOGGER.info("wxTemplateDTO = {}", wxTemplateDTO);
        return RpcResultBuilder.succSimple(wxTemplateDTO);
    }

    /**
     * 查询模板记录 - 倒序
     *
     * @param request 公众号和类型
     * @return
     */
    Example buildLogExample(TemplateLastUseQueryRequest request) {
        Example example = new Example(WxSendTemplateLog.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("appId", request.getAppId());
        if (Objects.nonNull(request.getTemplateLogType())) {
            criteria.andEqualTo("templateLogType", request.getTemplateLogType());
        }
        example.orderBy("gmt_create").desc();
        return example;
    }
}
